home *** CD-ROM | disk | FTP | other *** search
-
- /* C O P Y R I G H T N O T I C E : */
- /* Copyright 1986 Eric Jul and Norm Hutchinson. May not be used for any */
- /* purpose without written permission from the authors. */
-
- #include <stdio.h>
- #include <a.out.h>
- #include <setjmp.h>
-
- #include "Kernel/h/assert.h"
- #include "Kernel/h/system.h"
- #include "Kernel/h/emTypes.h"
- #include "Kernel/h/kmdTypes.h"
- #include "Kernel/h/consts.h"
-
- extern int *NlistValueOf();
- extern void CodeDependency();
- extern GODP CreateGODEntry();
- extern ODP KernelCheatingCreate();
- extern AbConPtr OIDOIDOIDToAbCon();
- extern RODataPtr OIDToODAP();
- extern unsigned int OpNumberToAddress();
- extern char *PPSSPlace(), *PPPOID(), *PPGOID(), *PPFindLineNo(),
- *PPOID(), *PPCOID(), *PPCodePtr();
- /*
- * This routine imports:
- * ODP OIDToODP(id); OID id;
- * AbConPtr OIDOIDToAbCon(atid, rid, ctid); OID atid, ctid;
- * RODataPtr OIDToODAP(id, codeid); OID id, codeid;
- * unsigned int OpNumberToAddress(id, opNumber); OID id; int opNumber;
- * int *NlistValueOf(name); char *name;
- *
- * jmp_buf errorExitPoint;
- */
-
- extern jmp_buf errorExitPoint;
-
- #define OIDToODP OTLookup
- extern ODP OTLookup();
-
- #define Check(condition,err) assert(condition);
-
- /* When the translation routines are asked to return an address of a routine
- which it does not know about, it returns the address of the label
- BadJump in the kernel stub.
- The kernel stub inturn calls BadJumpOccurred which abort with
- an error message.
- */
- extern int BadJump;
-
- void BadJumpOccurred()
- {
-
- ErrMsg("Local invocation attempt; but code is non-resident\n");
- ErrMsg("Jump from %s\n", PPSSPlace(currentSSP));
- abort();
- }
-
- void translateDoto(fDotoPtr)
- DotoFilePtr fDotoPtr;
- {
- register int i;
- register struct nlist*nl;
- register struct relocation_info
- *rl;
- long numSymbols, *relocatedAddress, symbolValue;
- char **symbolNames;
- RelocationInfoPtr riptr;
- ARelocation ar;
- CodePtr cptr;
- CodeODP theCodeODP;
- ODP cheatingODP;
-
- Check(NonNULL(fDotoPtr), 40);
- cptr = dotoCodePtr(fDotoPtr);
- Check(cptr->tag.tag == CodeTag, 41);
- numSymbols = fDotoPtr->header.a_syms / sizeof(struct nlist);
- KMDTrace("Translate", 2, "Translating %s\n", PPCOID(cptr->ownOID));
- if (numSymbols > 0) {
- symbolNames = (char **) malloc((unsigned) (numSymbols * sizeof(char *)));
- for (i = 0; i < numSymbols; i++) {
- nl = dotoSymbolPtr(fDotoPtr) + i;
- symbolNames[i] = dotoStringPtr(fDotoPtr)+nl->n_un.n_strx;
- KMDTrace("Translate", 6, "Symbol #%3d: %s\n", i, symbolNames[i]);
- }
- }
-
- for (i = 0; i < fDotoPtr->header.a_drsize / sizeof(struct relocation_info); i++) {
- rl = dotoRelocPtr(fDotoPtr) + i;
- if (rl->r_pcrel) continue;
- Check(rl->r_length == 2, 42);
- Check(rl->r_extern, 43);
- Check(rl->r_symbolnum < numSymbols, 43);
- symbolValue = (unsigned int) NlistValueOf(symbolNames[rl->r_symbolnum]);
- assert(-1 != symbolValue);
- KMDTrace("Translate", 7, "NlistValueOf returned 0x%08x\n", symbolValue);
- relocatedAddress = (long *) addOffset(cptr, rl->r_address);
- *relocatedAddress = symbolValue;
- KMDTrace("Translate", 6, "Addr 0x%05x set to 0x%05x\n", relocatedAddress,
- symbolValue);
- /* obsolete *((long *)((char *)cptr + rl->r_address)) = symbolValue; */
- }
- if (numSymbols > 0) {
- free((char *)symbolNames);
- }
- /* Now do the Emerald relocation */
- if (IsNULL(cptr->relocationInfoOffset)) return;
- riptr = (RelocationInfoPtr) addOffset(cptr, cptr->relocationInfoOffset);
- KMDTrace("Translate", 3, "Emerald Relocation %d relocation items\n",
- riptr->numEntries);
- for (i = 0; i < riptr->numEntries; i++) {
- ar = riptr->relocation[i];
- relocatedAddress = (long *) addOffset(cptr, ar.where);
- KMDTrace("Translate", 5, "%s: rel loc %d, abs 0x%05x (0x%05x, 0x%05x))\n",
- ar.kind == AR_OIDToODP ? "OIDToODP" :
- ar.kind == AR_OIDToODAP ? "OIDToODAP" :
- ar.kind == AR_OpNumberToAddress ? "OpNumberToAddress" :
- ar.kind == AR_OIDOIDToAbCon ? "OIDOIDToAbCon" :
- ar.kind == AR_OIDToCheatingODP ? "OIDToCheatingODP":
- ar.kind == AR_OIDToCodePtr ? "OIDToCodePtr" :
- "Unknown translation",
- ar.where, relocatedAddress, ar.theOID1, ar.theOID2);
- switch (ar.kind) {
- case AR_OIDToODP:
- symbolValue = (int) OIDToODP(ar.theOID1);
- if (symbolValue == NULL) {
- /* It is not known here, so fake one */
- symbolValue = (int) CreateGODEntry(ar.theOID1, ar.theOID2);
- }
- KMDTrace("Translate", 3, "AR_OIDToODP: 0x%08x to 0x%08x\n",
- ar.theOID1, symbolValue);
- break;
- case AR_OIDToODAP:
- symbolValue = (int) OIDToODAP(ar.theOID1, ar.theOID2);
- KMDTrace("Translate", 3, "AR_OIDToODAP: 0x%08x to 0x%08x\n",
- ar.theOID1, symbolValue);
- break;
- case AR_OpNumberToAddress:
- symbolValue = (int) OpNumberToAddress(ar.theOID1, (int) ar.theOID2);
- KMDTrace("Translate", 3, "AR_OpNumberToAddress: 0x%08x to 0x%08x\n",
- ar.theOID1, symbolValue);
- if (IsNULL(symbolValue)) {
- CodeDependency(cptr->ownOID, ar.theOID1);
- symbolValue = (int) &BadJump;
- }
- break;
- case AR_OIDOIDToAbCon:
- symbolValue = (int) OIDOIDOIDToAbCon(ar.theOID1, (OID) EMNIL,
- ar.theOID2);
- KMDTrace("Translate", 3,
- "AR_OIDOIDToAbCon(0x%08x, 0x%08x) -> AbCon at 0x%08x\n",
- ar.theOID1, ar.theOID2, symbolValue);
- break;
- case AR_OIDToCheatingODP:
- cheatingODP = OIDToODP(ar.theOID1);
- symbolValue = (int) cheatingODP;
- if (IsNULL(cheatingODP) || IsNULL(cheatingODP->G.ownLoc)) {
- /* We have to create it */
- symbolValue =
- (int) KernelCheatingCreate(ar.theOID1, ar.theOID2, 0, (AVariable *)0);
- KMDTrace("Code", 2, "Cheating create of %s, one of %s\n",
- PPGOID(ar.theOID1), PPCOID(ar.theOID2));
- } else {
- KMDTrace("Code", 4,
- "Cheating object %s already exists at 0x%04x\n",
- PPGOID(cheatingODP->G.ownOID), cheatingODP->G.ownLoc);
- }
- KMDTrace("Translate", 3, "AR_OIDToCheatingODP(%s, %s)\n",
- PPGOID(ar.theOID1), PPCOID(ar.theOID2));
- break;
- case AR_OIDToCodePtr:
- theCodeODP = (CodeODP) OIDToODP(ar.theOID1);
- assert(NonNULL(theCodeODP));
- symbolValue = (int) theCodeODP->dataPtr;
- assert(NonNULL(symbolValue));
- KMDTrace("Translate", 3, "AR_OIDToCodePtr %s\n", PPCOID(ar.theOID1));
- break;
- default:
- Check(FALSE, 44);
- break;
- }
- KMDTrace("Translate", 5, " (0x%08x) <- 0x%08x\n", relocatedAddress, symbolValue);
- *relocatedAddress = symbolValue;
- }
- }
- /**********************************************************************/
- /* retranslate */
- /**********************************************************************/
-
- void retranslate(fCodeODP)
- CodeODP fCodeODP;
- /* A previously remote piece of code has arrived, so do the necessary
- retranslates.
- */
- {
- KMDTrace("Code", 3, "Retranslating %s\n", PPCOID(fCodeODP->ownOID));
- KMDTrace("FixMe", 5, "Do only the necessary translations\n");
-
- /* For now just redo the entire translation */
- translateDoto(mDotoFilePtrFromCodePtr(fCodeODP->dataPtr));
- }
-